package cn.edu.cug.cs.gtl.plugins.catalog.tree;

import cn.edu.cug.cs.gtl.apis.ui.datake.catalogtree.CatalogTree;
import cn.edu.cug.cs.gtl.apis.ui.datake.catalogtree.JTreeTools;
import cn.edu.cug.cs.gtl.apis.ui.tree.TreeNodeData;
import cn.edu.cug.cs.gtl.plugins.catalog.utils.HdfsFileUtils;
import cn.edu.cug.cs.gtl.protos.DataCatalog;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.ExpandVetoException;
import java.awt.event.*;
import java.io.IOException;

public class MountExistDirDialog extends JFrame {
    private FileSystem fs;
    private JTree tree;
    private DefaultTreeModel treeModel;
    private JPopupMenu popupMenu;
    private CatalogTree catalogTree;

    static class HdfsNode {
        private final String name;
        private final String path;

        public HdfsNode(String name, String path) {
            this.name = name;
            this.path = path;
        }

        public String getPath() {
            return path;
        }

        @Override
        public String toString() {
            return name;
        }
    }

    public MountExistDirDialog(CatalogTree catalogTree) throws IOException {
        this.catalogTree = catalogTree;
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://202.114.198.141:8020/"); // 替换为您的 HDFS URI
        this.fs = FileSystem.get(conf);

        initTree();
        initUI();
        initPopupMenu();
    }

    //树型目录鼠标事件监视器
    private class MyMouseAdapter extends MouseAdapter {
        public void mousePressed(MouseEvent e) {
            if (SwingUtilities.isRightMouseButton(e)) {
                //判断右键点击的是目录还是文件，如果是目录就显示popupMenu
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                HdfsNode hdfsNode = (HdfsNode) selectedNode.getUserObject();
                int ret = HdfsFileUtils.isFileOrDir(fs, hdfsNode.getPath());
                if (ret == 0) {
                    int row = tree.getClosestRowForLocation(e.getX(), e.getY());
                    tree.setSelectionRow(row);
                    popupMenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        }
    }

    private class MyTreeWillExpandListener implements TreeWillExpandListener {
        @Override
        public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
            HdfsNode hdfsNode = (HdfsNode) node.getUserObject();

            System.out.println("node.getUserObject()" + node.getUserObject());
            System.out.println("hdfsNode" + hdfsNode);
            // 检查是否为占位子节点，如果是，则加载真正的子节点
            if ((node.getChildCount() == 1) && ((DefaultMutableTreeNode) node.getChildAt(0)).getUserObject() == null) {
                node.removeAllChildren(); // 移除占位子节点
                try {
                    loadChildren(node, hdfsNode.getPath());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
            // 折叠时无需执行特殊操作
        }
    }

    private void initTree() throws IOException {
        // 创建根节点
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(new HdfsNode("/data/lake", "/data/lake"));
        this.treeModel = new DefaultTreeModel(rootNode);
        this.tree = new JTree(treeModel);

        // 添加鼠标事件监视器
        tree.addMouseListener(new MyMouseAdapter());

        // 添加节点展开监听器
        tree.addTreeWillExpandListener(new MyTreeWillExpandListener());

        // 加载根目录的子节点
        loadChildren(rootNode, "/data/lake");
    }

    private void initUI() {
        setTitle("HDFS Browser");
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        add(new JScrollPane(tree));
        setSize(400, 500);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void initPopupMenu() {
        popupMenu = new JPopupMenu();
        JMenuItem addItem = new JMenuItem("挂载");
        addItem.addActionListener(new MyActionListener());
        popupMenu.add(addItem);
    }

    private class MyActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            //获取用户在对话框中目录树上右键选中的节点
            DefaultMutableTreeNode treeSelectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
            HdfsNode hdfsNode = (HdfsNode) treeSelectedNode.getUserObject();

            //用户在geospacex的数据目录栏中树上右键选中的节点
            DefaultMutableTreeNode catalogTreeSelectedNode = (DefaultMutableTreeNode) catalogTree.getLastSelectedPathComponent();
            DataCatalog dataCatalog = (DataCatalog) ((TreeNodeData) catalogTreeSelectedNode.getUserObject()).getRefObject();

            //HDFS文件系统下文件夹合法性判断
            boolean ret = false;
            try {
                ret = HdfsFileUtils.checkHDFSFolder(fs, new Path(hdfsNode.getPath()));
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            if (!ret) {
                JOptionPane.showMessageDialog(null, "选中的文件夹不合法");
                return;
            }

            //调用挂载函数
            try {
                HdfsFileUtils.mountFile(fs, dataCatalog.getName(), hdfsNode.getPath());
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }

            //移除鼠标选中节点的所有子节点
            catalogTreeSelectedNode.removeAllChildren();
            //通知树模型节点结构已修改
            DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
            treeModel.nodeStructureChanged(catalogTreeSelectedNode);
            //重新从数据库中加载树结构信息
            JTreeTools.createBranch(catalogTree, catalogTreeSelectedNode);
        }
    }

    private void loadChildren(DefaultMutableTreeNode node, String path) throws IOException {
        FileStatus[] statuses = fs.listStatus(new Path(path));
        for (FileStatus status : statuses) {
            String childPath = status.getPath().toString();
            HdfsNode childNode = new HdfsNode(childPath.substring(childPath.lastIndexOf('/') + 1), childPath);
            DefaultMutableTreeNode childTreeNode = new DefaultMutableTreeNode(childNode);

            // 如果是目录，添加一个占位的子节点
            if (status.isDirectory()) {
                childTreeNode.add(new DefaultMutableTreeNode(null));
            }

            treeModel.insertNodeInto(childTreeNode, node, node.getChildCount());
        }
    }
}

